#include "constraintswindow.h"
#include "dowconstraintwindow.h"
#include "../andconstraint.h"
#include "../logger.h"
#include "../dowconstraint.h"

ConstraintsWindow::ConstraintsWindow(BaseObjectType* cobject,
									 const Glib::RefPtr<Gnome::Glade::Xml>& ui_xml)
	: Gtk::Dialog(cobject),
	  cancel_button_(0),
	  ok_button_(0),
      add_constraint_button_(0),
      remove_constraint_button_(0),
      clear_constraints_button_(0),
      constraint_types_treeview_(0),
      constraints_treeview_(0)
{
	// connect a handler to the delete-event signal, which is sent when the
	// user closes the window
	signal_delete_event().connect(
		sigc::mem_fun(*this, &ConstraintsWindow::on_delete_event));

	// initialize and set up child widgets
	ui_xml->get_widget("cancel_button", cancel_button_);
	cancel_button_->signal_clicked().connect(
		sigc::mem_fun(*this, &ConstraintsWindow::on_cancel));
	ui_xml->get_widget("ok_button", ok_button_);
	ok_button_->signal_clicked().connect(
		sigc::mem_fun(*this, &ConstraintsWindow::on_ok));
	ui_xml->get_widget("add_constraint_button", add_constraint_button_);
	add_constraint_button_->signal_clicked().connect(
		sigc::mem_fun(*this, &ConstraintsWindow::on_add_constraint));
	ui_xml->get_widget("remove_constraint_button", remove_constraint_button_);
	remove_constraint_button_->signal_clicked().connect(
		sigc::mem_fun(*this, &ConstraintsWindow::on_remove_constraint));
	ui_xml->get_widget("clear_constraints_button", clear_constraints_button_);
	clear_constraints_button_->signal_clicked().connect(
		sigc::mem_fun(*this, &ConstraintsWindow::on_clear_constraints));

	ui_xml->get_widget("constraint_types_treeview", constraint_types_treeview_);
	ui_xml->get_widget("constraints_treeview", constraints_treeview_);
    init_types_treeview();
    init_constraints_treeview();
}

ConstraintsWindow::~ConstraintsWindow()
{
}

void ConstraintsWindow::init_types_treeview()
{
    // set up constraint types tree widget;  model, columns ...
    constraint_types_treeview_model_ = Gtk::TreeStore::create(
        constraint_types_treeview_columns_);

    constraint_types_treeview_->set_model(constraint_types_treeview_model_);

    constraint_types_treeview_->append_column("Type",
                                              constraint_types_treeview_columns_.type);

    // add rows
    constraint_types_treeview_model_->clear();
    Gtk::TreeModel::Row row(*(constraint_types_treeview_model_->append()));
    row[constraint_types_treeview_columns_.type] = "Day of Week";
    row = *(constraint_types_treeview_model_->append());
    row[constraint_types_treeview_columns_.type] = "Time of Day";
}

void ConstraintsWindow::init_constraints_treeview()
{
    // set up constraint tree widget;  model, columns ...
    constraints_treeview_model_ = Gtk::TreeStore::create(
        constraints_treeview_columns_);

    constraints_treeview_->set_model(constraints_treeview_model_);

    constraints_treeview_->append_column("Type",
                                         constraints_treeview_columns_.type);
    constraints_treeview_->append_column("Value",
                                         constraints_treeview_columns_.value);
}

/// Handler for the signal emitted when the user clicks the Cancel button.
void ConstraintsWindow::on_cancel()
{
    on_clear_constraints();
	hide();
	response(Gtk::RESPONSE_REJECT);
}

/// Handler for the signal emitted when the user clicks the Ok button.
void ConstraintsWindow::on_ok()
{
	hide();
	response(Gtk::RESPONSE_ACCEPT);
}

/// Handler for the signal emitted when the user clicks the Ok button.
void ConstraintsWindow::on_add_constraint()
{
    Logger::instance()->warning("The Add Constraint button was clicked, but "
                                "isn't implemented yet.", 3);

	Glib::RefPtr<Gnome::Glade::Xml> ui_xml =
		Gnome::Glade::Xml::create("dow_constraint_window.glade");
	DOWConstraintWindow* dow_constraint_window = 0;
	ui_xml->get_widget_derived("dow_constraint_window", dow_constraint_window);
	int response = dow_constraint_window->run();

	switch( response ) {
	case Gtk::RESPONSE_ACCEPT: {
        // update constraints to be disjuntion of all constraints we have with
        // the new constraint
        boost::shared_ptr<Constraint> dow_constraint(
            dow_constraint_window->constraint());
        boost::shared_ptr<Constraint> disjunction(
            new AndConstraint(dow_constraint, constraints()));
        constraints(disjunction);
        Gtk::TreeModel::Row row(*(constraints_treeview_model_->append()));
        row[constraints_treeview_columns_.type] = "Day of Week";
        row[constraints_treeview_columns_.value] = dow_constraint->to_string();
        Logger::instance()->warning("DOW Constraints are not implemented yet.", 1);
		break;
	}
	default:
		break;
	}
}

/// Handler for the signal emitted when the user clicks the Ok button.
void ConstraintsWindow::on_remove_constraint()
{
    Logger::instance()->warning("The Remove Constraint button was clicked, but "
                                "isn't implemented yet.", 3);
}

/// Handler for the signal emitted when the user clicks the Ok button.
void ConstraintsWindow::on_clear_constraints()
{
    Logger::instance()->warning("The Clear Constraints button was clicked, but "
                                "isn't implemented yet.", 3);
    constraints(boost::shared_ptr<Constraint>()); // reset constraints
    constraints_treeview_model_->clear();         // clear tree widget
}

/// Handler for the signal emitted when the user closes the window.
bool ConstraintsWindow::on_delete_event(GdkEventAny*)
{
	on_cancel();
	return true;
}

boost::shared_ptr<Constraint> ConstraintsWindow::constraints() const
{
    return constraints_;
}

void ConstraintsWindow::constraints(boost::shared_ptr<Constraint> constraint)
{
    constraints_ = constraint;
}
